/** 
 *  @file
 *  @brief 热分析测试带参模板
 *  @author  ytl
 *  @date    2025.01.03
 *  @version  v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */

#pragma once

#include "gtest/gtest.h"

#include "Utility/FileSystem/SGFileSystem.h"

#include "DataStructure/Input/Solver/Project.h"
#include "DBManager/Database/DatabaseFactory.h"
#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Subcase/ISubcaseService.h"

#include "Import/ImportAPI/ImportAPI.h"
#include "Export/VTKExport/VTKExport.h"
// #include "../../Common/AnalysisProcess.h"
#include "../ThermalSolver.h"

using namespace SG::Utility::FileSystem;
using SG::DataStructure::Common::Status;
using SG::DataStructure::FEM::Project;
using namespace SG::DBManager;

extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;

struct ThermalTestModel
{
    std::string inputFile;
    std::string targetFile;
};

class ThermalTest : public ::testing::TestWithParam<ThermalTestModel>
{
protected:
    void SetUp () override
    {
        modelPath = getTestDataPath ("SGFem/Task/Input/");
        resultFilePath = getTestDataPath ("SGFem/Task/");
    }

    void TearDown () override
    {
        DB_SERVICEFACTORY->ClearDatabase ();
    }
    std::string modelPath; ///< 输入模型文件路径
    std::string resultFilePath; ///< 期望结果（正确）文件路径
};

TEST_P (ThermalTest, ComputeTemperatureAsExpect)
{
    ThermalTestModel para = GetParam ();
    Project project;
    project.m_modelFilePath = modelPath;
    project.m_modelFileName = para.inputFile;
    auto posi = para.inputFile.find('.');
    project.m_jobName = para.inputFile.substr(0, posi);

    DB_SERVICEFACTORY->ClearDatabase ();
    
    SG::Import::SGImporter importer (DB_SERVICEFACTORY);
    auto status = importer.Import (project.m_modelFilePath + project.m_modelFileName);

    ASSERT_EQ (status, Status::STATUS_Success);
    
    // 获取模型中所有的subCase
    auto subcaseIds = DB_SERVICEFACTORY->get<ISubcaseService> ()->GetAllSubcaseID ();

    ThermalSolver::Solve (DB_SERVICEFACTORY, project, subcaseIds);
    SG::Post::vtkOutput (DB_SERVICEFACTORY, project.m_workSpace + project.m_jobName + ".vtk");

    // Check
    auto fileTest = getFullPath (project.m_jobName + ".vtk");
    auto fileTarget = resultFilePath + para.targetFile;
    
    ASSERT_TRUE (compareVTK (fileTarget, fileTest));
};

/** 4节点平面单元
 * 
 */
INSTANTIATE_TEST_CASE_P (Quad4Element, ThermalTest, testing::Values(
    ThermalTestModel{"SteadyThermal_Quad4_QBDY3_conv_flux.bdf", "SteadyThermal_Quad4_QBDY3_conv_flux.vtk"},
    ThermalTestModel{"SteadyThermal_Quad4tria3_conv_flux.bdf", "SteadyThermal_Quad4tria3_conv_flux.vtk"}
));

/** 8节点六面体单元
 * 
 */
INSTANTIATE_TEST_CASE_P (Hexa8Element, ThermalTest, testing::Values(
    ThermalTestModel{"SteadyThermal_Hexa8Tetra4_conv_flux.bdf", "SteadyThermal_Hexa8Tetra4_conv_flux.vtk"}
));

/** 3节点平面单元
 * 
 */
// INSTANTIATE_TEST_CASE_P (Tria3Element, ThermalTest, testing::Values(
// ));

/** 4节点四面体单元
 * 
 */
// INSTANTIATE_TEST_CASE_P (Tetra4Element, ThermalTest, testing::Values(
// ));






